/*
 * Copyright (c) 2011-2021, baomidou (jobob@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.wdg.mybatisplus.base;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.*;
//import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ResolvableType;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 *  @Description IService 实现类（ 泛型：M 是 mapper 对象，T 是实体 ）
 *  
 *  @author wudiguang
 *  @Date 2021/11/15
 */ 
@SuppressWarnings("unchecked")
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {

//    protected Log log = LogFactory.getLog(getClass());
//
//    @Autowired
//    protected M baseMapper;
//
//    @Override
//    public M getBaseMapper() {
//        return baseMapper;
//    }
//
//    protected Class<T> entityClass = currentModelClass();
//
//    @Override
//    public Class<T> getEntityClass() {
//        return entityClass;
//    }
//
//    protected Class<T> mapperClass = currentMapperClass();
//
//    /**
//     * 判断数据库操作是否成功
//     *
//     * @param result 数据库操作返回影响条数
//     * @return boolean
//     * @deprecated 3.3.1
//     */
//    @Deprecated
//    protected boolean retBool(Integer result) {
//        return SqlHelper.retBool(result);
//    }
//
//    protected Class<T> currentMapperClass() {
//        return (Class<T>) this.getResolvableType().as(ServiceImpl.class).getGeneric(0).getType();
//    }
//
//    protected Class<T> currentModelClass() {
//        return (Class<T>) this.getResolvableType().as(ServiceImpl.class).getGeneric(1).getType();
//    }
//
//    /**
//     * @see ResolvableType
//     * @since 3.4.3
//     */
//    protected ResolvableType getResolvableType() {
//        return ResolvableType.forClass(ClassUtils.getUserClass(getClass()));
//    }
//
//    /**
//     * 批量操作 SqlSession
//     *
//     * @deprecated 3.3.0
//     */
//    @Deprecated
//    protected SqlSession sqlSessionBatch() {
//        return SqlHelper.sqlSessionBatch(entityClass);
//    }
//
//    /**
//     * 释放sqlSession
//     *
//     * @param sqlSession session
//     * @deprecated 3.3.0
//     */
//    @Deprecated
//    protected void closeSqlSession(SqlSession sqlSession) {
//        SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(entityClass));
//    }
//
//    /**
//     * 获取 SqlStatement
//     *
//     * @param sqlMethod ignore
//     * @return ignore
//     * @see #getSqlStatement(SqlMethod)
//     * @deprecated 3.4.0
//     */
//    @Deprecated
//    protected String sqlStatement(SqlMethod sqlMethod) {
//        return SqlHelper.table(entityClass).getSqlStatement(sqlMethod.getMethod());
//    }
//
//    /**
//     * 批量插入
//     *
//     * @param entityList ignore
//     * @param batchSize  ignore
//     * @return ignore
//     */
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public boolean saveBatch(Collection<T> entityList, int batchSize) {
//        String sqlStatement = getSqlStatement(SqlMethod.INSERT_ONE);
//        return executeBatch(entityList, batchSize, (sqlSession, entity) -> sqlSession.insert(sqlStatement, entity));
//    }
//
//    /**
//     * 获取mapperStatementId
//     *
//     * @param sqlMethod 方法名
//     * @return 命名id
//     * @since 3.4.0
//     */
//    protected String getSqlStatement(SqlMethod sqlMethod) {
//        return SqlHelper.getSqlStatement(mapperClass, sqlMethod);
//    }
//
//    /**
//     * TableId 注解存在更新记录，否插入一条记录
//     *
//     * @param entity 实体对象
//     * @return boolean
//     */
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public boolean saveOrUpdate(T entity) {
//        if (null != entity) {
//            TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass);
//            Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
//            String keyProperty = tableInfo.getKeyProperty();
//            Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
//            Object idVal = ReflectionKit.getFieldValue(entity, tableInfo.getKeyProperty());
//            return StringUtils.checkValNull(idVal) || Objects.isNull(getById((Serializable) idVal)) ? save(entity) : updateById(entity);
//        }
//        return false;
//    }
//
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
//        TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
//        Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
//        String keyProperty = tableInfo.getKeyProperty();
//        Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
//        return SqlHelper.saveOrUpdateBatch(this.entityClass, this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> {
//            Object idVal = ReflectionKit.getFieldValue(entity, keyProperty);
//            return StringUtils.checkValNull(idVal)
//                || CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
//        }, (sqlSession, entity) -> {
//            MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
//            param.put(Constants.ENTITY, entity);
//            sqlSession.update(getSqlStatement(SqlMethod.UPDATE_BY_ID), param);
//        });
//    }
//
//    @Transactional(rollbackFor = Exception.class)
//    @Override
//    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
//        String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
//        return executeBatch(entityList, batchSize, (sqlSession, entity) -> {
//            MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
//            param.put(Constants.ENTITY, entity);
//            sqlSession.update(sqlStatement, param);
//        });
//    }
//
//    @Override
//    public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {
//        if (throwEx) {
//            return baseMapper.selectOne(queryWrapper);
//        }
//        return SqlHelper.getObject(log, baseMapper.selectList(queryWrapper));
//    }
//
//    @Override
//    public Map<String, Object> getMap(Wrapper<T> queryWrapper) {
//        return SqlHelper.getObject(log, baseMapper.selectMaps(queryWrapper));
//    }
//
//    @Override
//    public <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper) {
//        return SqlHelper.getObject(log, listObjs(queryWrapper, mapper));
//    }
//
//    /**
//     * 执行批量操作
//     *
//     * @param consumer consumer
//     * @since 3.3.0
//     * @deprecated 3.3.1 后面我打算移除掉 {@link #executeBatch(Collection, int, BiConsumer)} }.
//     */
//    @Deprecated
//    protected boolean executeBatch(Consumer<SqlSession> consumer) {
//        return SqlHelper.executeBatch(this.entityClass, this.log, consumer);
//    }
//
//    /**
//     * 执行批量操作
//     *
//     * @param list      数据集合
//     * @param batchSize 批量大小
//     * @param consumer  执行方法
//     * @param <E>       泛型
//     * @return 操作结果
//     * @since 3.3.1
//     */
//    protected <E> boolean executeBatch(Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer) {
//        return SqlHelper.executeBatch(this.entityClass, this.log, list, batchSize, consumer);
//    }
//
//    /**
//     * 执行批量操作（默认批次提交数量{@link IService#DEFAULT_BATCH_SIZE}）
//     *
//     * @param list     数据集合
//     * @param consumer 执行方法
//     * @param <E>      泛型
//     * @return 操作结果
//     * @since 3.3.1
//     */
//    protected <E> boolean executeBatch(Collection<E> list, BiConsumer<SqlSession, E> consumer) {
//        return executeBatch(list, DEFAULT_BATCH_SIZE, consumer);
//    }

}
